//
//  UserData.swift
//  WeiBoDemo
//
//  Created by chaowen deng on 2021/3/24.
//

import Foundation
import Combine

class UserData: ObservableObject {
    // 只有 用@Published修饰的属性，才能在数据更新时，保证所有的页面数据都是更新的
    @Published var recomendPostList: PostList = loadPostListData("PostListData_recommend_1.json")
    @Published var hotPostList: PostList = loadPostListData("PostListData_hot_1.json")
    
    @Published var isRefreshing: Bool = false
    @Published var isLoadingMore: Bool = false
    @Published var loadingError: Error?
    
    private var recomendPostDic: [Int: Int] = [:] // id: index
    private var hotPostDic: [Int: Int] = [:]
    
    init() {
        for i in 0..<recomendPostList.list.count {
            let post = recomendPostList.list[i]
            recomendPostDic[post.id] = i
        }
        
        for i in 0..<hotPostList.list.count {
            let post = hotPostList.list[i]
            hotPostDic[post.id] = i
        }
        
    }
}

extension UserData {
    var showLoadingError: Bool { loadingError != nil }
    var loadingErrorText: String { loadingError?.localizedDescription ?? "" }
    
    
    /// 通过category获取对应的列表数据
    func postList(for category: PostListCategory) -> PostList {
        switch category {
        case .recomend: return recomendPostList
        case .hot: return hotPostList
        }
    }
    
    /// 下拉刷新获取数据
    func refreshPostLost(for category: PostListCategory) {
        switch category {
        case .recomend:
            NetworkAPI.recommendPostList { result in
                switch result {
                case let .success(list): self.handleRefreshPostList(list, for: category)
                case let .failure(error): self.handleLoadingError(error)
                }
                self.isRefreshing = false
            }
        
        case .hot:
            NetworkAPI.hotPostList { result in
                switch result {
                case let .success(list): self.handleRefreshPostList(list, for: category)
                case let .failure(error): self.handleLoadingError(error)
                }
                self.isRefreshing = false
            }
            
        }
    }
    
    /// 上拉加载更多
    func loadMorePostList(for category: PostListCategory) {
        
        // 为了提炼代码,将闭包里 相同的代码 提炼成一个临时变量
        let completion: (Result<PostList, Error>) -> Void = { result in
            switch result {
            case let .success(list) : self.handleLoadMorePostList(list, for: category)
            case let .failure(error) : self.handleLoadingError(error)
            }
            self.isLoadingMore = false
        }
        if isLoadingMore { return }
        isLoadingMore = true
        
        // 这里数据有限，就重复加载了
        switch category {
        case .recomend:
            NetworkAPI.recommendPostList(completion: completion)
        case .hot:
            NetworkAPI.hotPostList(completion: completion)
        }
    }
    /// 处理加载更多 的数据
    private func handleLoadMorePostList(_ list: PostList, for category: PostListCategory) {
        switch category {
        case .recomend:
            for post in list.list {
                update(post)
                recomendPostList.list.append(post)
                recomendPostDic[post.id] = recomendPostList.list.count - 1
            }
            
        case .hot:
            for post in list.list {
                update(post)
                hotPostList.list.append(post)
                hotPostDic[post.id] = hotPostList.list.count - 1
            }
        }
    }
    
    /// 处理获取的数据
    private func handleRefreshPostList(_ list: PostList, for category: PostListCategory) {
        var tempList: [Post] = []
        var tempDic: [Int:Int] = [:]
        
        for (index, post) in list.list.enumerated() {
            if tempDic[post.id] != nil { continue }//重复了
            tempList.append(post)
            tempDic[post.id] = index
            update(post)
        }
        
        switch category {
        case .recomend:
            recomendPostList.list = tempList
            recomendPostDic = tempDic
        case .hot:
            hotPostList.list = tempList
            hotPostDic = tempDic
        }
        
    }
    /// 处理错误信息
    private func handleLoadingError(_ error: Error) {
        loadingError = error
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            self.loadingError = nil
        }
    }
        
    
    
    /// 通过id，找到一条数据
    func post(forId id: Int) -> Post? {
        if let index = recomendPostDic[id] {
            return recomendPostList.list[index]
        }
        if let index = hotPostDic[id] {
            return hotPostList.list[index]
        }
        return nil
    }
    
    /// 更新操作
    func update(_ post: Post) {
        if let index = recomendPostDic[post.id] {
            recomendPostList.list[index] = post
        }
        if let index = hotPostDic[post.id] {
            hotPostList.list[index] = post
        }
    }
}




enum PostListCategory {
    /// 推荐
    case recomend
    
    /// 热门
    case hot
}
